﻿package engine.scene
{
	import engine.GameData;
	import engine.data.ModelLocator;
	import engine.data.ResPath;
	import engine.data.SceneObject;
	import engine.display.Story.StoryLogic;
	import engine.display.Story.StoryMoveUI;
	import engine.display.TalkManage;
	import engine.display.newAttack.AttackLogic;
	import engine.event.CustomEvent;
	import engine.event.SceneEvent;
	import engine.event.ScenePlayerEvent;
	import engine.flag.GameDefine;
	import engine.flag.ResourcesPath;
	import engine.guide.GuideEvent;
	import engine.logic.EffectLoadManager;
	import engine.logic.event.LogicEvent;
	import engine.logic.loading.LoadingLogic;
	import engine.logic.login.WaitingForScene;
	import engine.logic.walk.Astar.ForbiddenAreaLogic;
	import engine.logic.walk.NpcIconManage;
	import engine.logic.walk.WalkLogic;
	import engine.logic.walk.WalkManager;
	import engine.net.event.CustomMsgEvent;
	import engine.net.messages.CustomToClientFlag;
	import engine.net.messages.CustomToServerFlag;
	import engine.net.mgr.SystemSender;
	import engine.newUi.FactionAttackLogic;
	import engine.newUi.FactionBossExitUI;
	import engine.newUi.FactionBossUI;
	import engine.newUi.PkListUI;
	import engine.newUi.RightTopIndexLogic;
	import engine.newUi.TourUI;
	import engine.newUi.WorldBossBloodUI;
	import engine.newUi.WorldBossExitUI;
	import engine.newUi.WorldMapLogic;
	import engine.scene.player.BasePlayerModel;
	import engine.sound.SoundManage;
	import engine.ui.AlertUI;
	import engine.ui.MainUIManager;
	import engine.ui.UIManage;
	
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.geom.Point;
	import flash.utils.getTimer;
	import flash.utils.setTimeout;
	
	import newx.StageInfo;
	import newx.com.LayoutType;
	import newx.com.ResManager;
	import newx.com.config.StaticIni;
	import newx.com.loader.SwfLoader;
	import newx.utils.debug.IO;

	/**
	 *场景管理 
	 * @author 
	 * 
	 */
	public class SceneManager
	{
		private static var	_self	:SceneManager;
		
		/**主数据源*/
		private var _model				:ModelLocator;
		
		private var _end				:Boolean	=	true;
		
		private var _mask				:Shape;
		
		private var walkPoint			:String;
		
		public static var isCreate	:Boolean 	= 	false;
		
		private var _walkPlacePoints	:Object;
		/**场景视图对象**/
		private var _norSceneView		:SceneView;
		
		public var _sceneClickLogic	:SceneClickLogic;
		
		private var _isDeadWay			:Boolean	=	false;
		
		private var _loading			:Boolean	=	false;
		
		public static var _itemIconLoad		:Boolean	=	false;
		
		public static function getInstance():SceneManager
		{
			if ( _self == null )
			{
				_self = new SceneManager();
			}
			return _self;
		}
		
		public function SceneManager()
		{
			init();
		}
		
		private function init():void
		{
			_model			=	ModelLocator.getInstance();
			
			_sceneClickLogic=	new SceneClickLogic();
			
			//添加野外场景
			_norSceneView	=	new SceneView();
			StageInfo.sceneSpace.addChild(_norSceneView);
			
			SceneFrameLogic.getInstance();
			
			_walkPlacePoints=	StaticIni.getIniObj( "WalkAreaXY" );
			
			//添加场景遮罩
			initMask();
			
			_model.addEventListener(String(CustomToClientFlag.SERVER_CUSTOMMSG_YLZG_SWITCHSCENE),onSwitchScene);		
			
			_model.addEventListener(String(CustomToClientFlag.CLIENT_CUSTOMMSG_LEAVE_SCENE), onLeaveScene);
			
			_model.addEventListener(String(CustomToClientFlag.SERVER_CUSTOMMSG_SCENE_NPC_CONFIG_LIST), onAttackPlayerList );
			
			_model.addEventListener( ScenePlayerEvent.ADD_NPC, onPlayerChange );
			_model.addEventListener( ScenePlayerEvent.REMOVE_NPC, onPlayerChange );
			_model.addEventListener( ScenePlayerEvent.UPDATA_NPC, onPlayerChange );
		}
		
		private function initMask():void
		{
			_mask	=	new Shape();
			
			_mask.graphics.beginFill(0xFF8800,.5);
			_mask.graphics.drawRect(0,0,StageInfo.rootW,StageInfo.rootH);
			_mask.graphics.endFill();
			_mask.width = StageInfo.rootMaxW;
			_mask.height = StageInfo.rootMaxH;
			StageInfo.mainSpace.addChild(_mask);
			
			_mask.visible	=	false;
		}
		
		public function onChangeSize():void
		{
			if( GameData.SceneType	==	GameDefine.SceneType_ForbiddenAreaScene )
			{
				_norSceneView.x	= -40;
				return;
			}
			else if( GameData.SceneType	!=	GameDefine.SceneType_Attack )//&& GameData.SceneType != GameDefine.SceneType_ForbiddenAreaScene
			{
				_norSceneView.changeSize();
				
				if(GameData.Role == null)
					return;
				GameData.Role.setSceneViewRect();
//				if( norSceneView.scenePlayerLogic.role != null )
//				{
//					( norSceneView.scenePlayerLogic.role as RoleModel ).setSceneViewRect();
//				}
			}
		}
		
		private function onLeaveScene(evt : CustomMsgEvent):void
		{
			_end  = true;
		}
		
		//加载场景资源
		private function loadSceneRes():void
		{
			WaitingForScene.start();
			IO.traceLog("开启进场景进度条");
			NxLoaderProxy.setVisible(false);
			LoadingLogic.getInstance().nxLoading.y	= 0;
			
			var sceneModel : int = GameData.SceneModel;
			
			var url		:String = 	ResourcesPath.getMinSceneModel( sceneModel );
			
			IO.traceLog("加载场景资源：", url );
			
//			if( isCreate )
//			{//第一次创建游戏
////				onChangeSize();
//				new CGLogic( function():void
//				{
//					SwfLoader.StartLoad( url, null, onSceneBGLoadComplete, [sceneModel, url] );
//				},ResPath.SWF+"CG.flv"
//				);
//				isCreate = false;
//			}
			/*else if(GameData.SceneType == GameDefine.SceneType_WorldBossScene && _model.scene.Role.CheckProperties("WorldPlayerTodayFirst") && _model.scene.Role.GetProperties("WorldPlayerTodayFirst") == 1)
			{
				new CGLogic(function():void
				{
					SwfLoader.StartLoad( url, null, onSceneBGLoadComplete, [sceneModel, url] );
				},ResPath.SWF+"WorldBoss.flv"
				);
			}*/
//			else
//			{
				IO.traceLog("加载缩略图：", url );
				
				SwfLoader.StartLoad( url, null, onSceneBGLoadComplete, [sceneModel, url] );
				
				if(PkListUI.getInstance())
				{
					//如果世界地图打开了，关闭
					if( WorldMapLogic.getInstance().ui.visible )
					{
						WorldMapLogic.getInstance().ui.hide();
					}
					//如果 游历界面打开 了， 关闭
					if(TourUI.getInstance().visible)
					{
						TourUI.getInstance().hide();
					}
					//华山论剑
					if(PkListUI.getInstance().visible)
					{
						PkListUI.getInstance().hide();
					}
				}
				
//			}
		}
		
		//场景资源加载完成
		private function onSceneBGLoadComplete(val:DisplayObject,pList:Array):void
		{
			IO.traceLog("缩略图加载成功");
			
			handleSceneComplete(val,pList);
		}
		private function handleSceneComplete(val:DisplayObject,pList:Array):void
		{
			IO.traceLog("进入场景：", GameData.SceneConfig, 
				"类型："	, GameData.SceneType, 
				"模型ID："	, GameData.SceneModel,
				"val："		,val);
			
			//如果加载的不是当前场景，什么都不做
			//主要是防止连续切场景的加载资源的先后顺序问题
			if( GameData.SceneModel	!=	pList[0] )	
			{
				WaitingForScene.end();
				return;
			}
			
			//资源加载有问题，忽略
			if( val != null && val.width !=0 && val.height != 0 )
			{
				//首先清除旧场景上的所有显示对象的引用及事件
				//删除旧场景
				_norSceneView.setSceneBG( val as MovieClip );
				IO.traceLog("进入场景地图小图资源加载成功");
			}
			IO.traceLog("开始显示场景");
//			_norSceneView.showScene();
			IO.traceLog("开始改变大小");
			onChangeSize();
			IO.traceLog("开始发场景OK消息");
			//发送clientready，开始监听obj消息
			onSceneEnd();
			
			IO.traceLog("进入场景等2秒进场景");
			//进入场景
			setTimeout( function():void
			{
				WaitingForScene.end();
				if( !AttackLogic.getInstance().fighting )
				{
					IO.traceLog("进入场景不处于战斗显示");
					showSceneView();
				}
				IO.traceLog("进入场景关闭进场景进度条");
			}, 2000 );
		}
		
		//客户端准备好了
		private function onSceneEnd():void
		{
			addPlayer( _model.scene.Role );
			
			_model.dispatchEvent(new SceneEvent(SceneEvent.SceneLoaded, [this]));
			// 向服务端发送Ready消息
			SystemSender.getInstance().CustomMsg(CustomToServerFlag.CLIENT_CUSTOMMSG_ON_CLIENT_READY);
			//告知服务器客户端加载好了
			SystemSender.getInstance().CustomMsg(CustomToServerFlag.CLIENT_CUSTOMMSG_CHECK_SEND_WINDOW);
			
			//加载战斗特效
			EffectLoadManager.loadEffectSwf();
		}
		
		/**
		 *	获取战斗场景中npc 
		 */		
		private function onAttackPlayerList(e:CustomMsgEvent):void
		{
			
			if( AttackLogic.getInstance().fighting && _loading )return;
			
			if( WorldBossBloodUI.getInstance().isAutoAttack && GameData.SceneType	==	GameDefine.SceneType_WorldBossScene) return;
			if( FactionBossUI.getInstance().isAutoAttack && GameData.SceneType	==	GameDefine.SceneType_FactionBossScene) return;
			if(e.pList.length>0)
			{
				var urlarr:Array = [];
				for(var i:int = 0;i<e.pList.length;i++)
				{
					var url		:String = 	ResPath.ACTORS + "npc_"+ e.pList[i] + ".swf" ;
					urlarr.push(url)
				}
				_model.addEventListener( SceneEvent.onLoadRoleComplete,onLoadRoleComplete);
				SceneRoleLoadLogic.getInstance().loadRoleRes(urlarr);
			}
			else
			{
				loadSceneRes();
			}
				
		}
		
		private function onLoadRoleComplete(e:SceneEvent):void
		{
			_model.removeEventListener( SceneEvent.onLoadRoleComplete,onLoadRoleComplete);
			loadSceneRes();
		}
		
		/**
		 * 进出场景（逻辑） 
		 * @param e
		 * 
		 */		
		public function onSwitchScene(e:CustomMsgEvent):void
		{
			WalkManager.getInstance().walkLogic.isReset	=	false;
			if(!_itemIconLoad)
			{
				setTimeout(function ():void
				{
					ResManager.loadRes("ItemIcon",ResPath.SWF + "ItemIcon.swf",
						function ():void
						{
							_itemIconLoad = true;
							_model.dispatchEvent(new LogicEvent(LogicEvent.ITEMICONLOADED));	
						});
				},10000);
			}
			_model.dispatchEvent( new GuideEvent( GuideEvent.CLOSE_GUIDE,[] ) );
			var storyComArr:Array = _model.scene.GetRecordEx("GutCompleted").recArr;
			
//			if(e.pList[2] == 11000100  && storyComArr.length < 1)
//			{//进入牛家村.且剧情是第一个.不进场景直接播放剧情
//				StoryMoveUI.getInstance()._sceneEvent = e;
//				StoryMoveUI.getInstance().showTalkInfo("Story_500001");
//				StoryLogic.getInstance().SendStoryID("Story_500001");
//				return;
//			}
//			
			if ( AttackLogic.getInstance().fighting ) 
			{//战斗的时候不切场景
				return;
			}
			
			//龙脉,帮派boss 防止连续切同一场景 比较特殊
			if( (GameData.SceneType	==	GameDefine.SceneType_WorldBossScene ||
				GameData.SceneType	==	GameDefine.SceneType_FactionBossScene) && 
				GameData.SceneConfig == e.pList[2] )
			{
				return;
			}
			
			if(GameData.SceneModel == e.pList[0] && GameData.SceneConfig == e.pList[2]) return;
			
			AlertUI.hideAlert();
			
			_loading=	false;
			
			_end	=	false;
			
			StageInfo.setLayout(LayoutType.TILE);
			
			//删除假场景数据
			_model.scene.Clear();
			NpcIconManage.getInstance().clearNpcItems();			
			TalkManage.getInstance().clearArray();
			//场景类型
			GameData.SceneType	=	e.pList[1];
			if(e.pList.length>3)
				GameData.EliteFBScene = e.pList[3];
			WalkLogic.SceneType = GameData.SceneType;
			
			if( GameData.SceneModel != e.pList[0] || GameData.SceneConfig != e.pList[2] )
			{
				//场景模型
				GameData.SceneModel	=	e.pList[0];
				//场景id
				GameData.SceneConfig=	e.pList[2];
				
				if(GameData.SceneType	==	GameDefine.SceneType_ForbiddenAreaScene)//SceneType_Normal;SceneType_ForbiddenAreaScene
				{
					var arr:Array	=	StaticIni.getIniVar("GridForbiddenArea_"+ GameData.SceneConfig,"position").split("|");
					arr.pop();
//					ForbiddenAreaLogic.getInstance().forbiddenInit();
					ForbiddenAreaLogic.getInstance().makeGrid(arr);
				}
				
				walkPoint = _walkPlacePoints.hasOwnProperty( GameData.SceneModel ) 
					? _walkPlacePoints[ GameData.SceneModel ] : _walkPlacePoints[ "normal" ];
				
				if(GameData.SceneType != GameDefine.SceneType_WorldBossScene)
				{
					//获取行走区域
					WalkManager.getInstance().findWayLogic.updaWalkPlace( walkPoint.split( "," ) );
				}
				
				//关闭所有打开的界面
				UIManage.getInstance().hideOpenedUI();
				
				_norSceneView.visible = false;
				
				if( GameData.SceneType == GameDefine.SceneType_CS || GameData.SceneType == GameDefine.SceneType_CSEntry )
				{
					SystemSender.getInstance().CustomMsg( CustomToServerFlag.CLIENT_CUSTOMMSG_REQUEST_NPC_INFO );
				}else
				{
					_loading = true;
					
					loadSceneRes();
				}
				
				SoundManage.getInstance().stopBG(true);

			};
			
			IO.traceLog("收到转场景消息：当前时间"+getTimer(),"目标场景modelID:"+e.pList[0]);
		}
		
		private function onPlayerChange( evt : ScenePlayerEvent ):void
		{
			switch( evt.type )
			{
				case ScenePlayerEvent.ADD_NPC:
				{
					addPlayer( evt.data as SceneObject );
					break;
				}
				case ScenePlayerEvent.REMOVE_NPC:
				{
					removePlayer( evt.data as SceneObject  );
					break;
				}
				case ScenePlayerEvent.UPDATA_NPC:
				{
					updataSceneObjByProperty( evt.data[ 0 ], evt.data[ 1 ] );
					break;
				}
			}
		}
		
		/**
		 * 加载场景上的建筑
		 * */
		private function addPlayer(tObj : SceneObject):void
		{
			if( !_end )
			{
				_norSceneView.scenePlayerLogic.addNpc(tObj);
			}
		}

		/**
		 *	删除场景obj 
		 */
		private function removePlayer(tObj : SceneObject):void
		{
			_norSceneView.scenePlayerLogic.removeNpcByObjId( tObj.ObjID );
		}
		
		/**
		 *	根据属性更新玩家信息 
		 */		
		private function updataSceneObjByProperty( tObj : SceneObject, propertyName : String ):void
		{
			_norSceneView.scenePlayerLogic.updataSceneObjByProperty( tObj, propertyName );
		}
		
		/**
		 *	改变舞台场景npc状态（任务npc） 
		 */
		public function changeNpcStage( npc : Array ):void
		{
			_norSceneView.scenePlayerLogic.changeNpcStage(npc);
		}
		
		/**
		 *	返回站位的 
		 * @param pos
		 * @return 
		 * 
		 */
		public function getPosMc(pos :Point):BasePlayerModel
		{
			return _norSceneView.scenePlayerLogic.getScenePlayerByID( pos );
		}
		/**
		 * 返回场景对像 
		 * @param val
		 * @return 
		 * 
		 */		
		public function getConfigMC(val:String):BasePlayerModel
		{
			return _norSceneView.scenePlayerLogic.getScenePlayByConfigID( val );
		}
		public function hideSceneView():void
		{
			MainUIManager.getInstance().intoScene( GameDefine.SceneType_Attack );
			
			_norSceneView.mouseChildren = _norSceneView.mouseEnabled = _norSceneView.visible = false;
			UIManage.getInstance().hideOpenedUI();
			
//			_norSceneView.alpha = 1;
//			TweenLite.to(_norSceneView, .3, {alpha:0});
		}
		
		public function showSceneView():void
		{
			IO.traceError( "showSceneView" );
			
			if( WorldMapLogic.getInstance().ui.visible ) return;
			
			MainUIManager.getInstance().intoScene( GameDefine.SceneType_Normal );
			
			RightTopIndexLogic.getInstance().changeRightTopIndexStage( GameData.SceneConfig, GameData.SceneType );
			
			_norSceneView.mouseChildren = _norSceneView.mouseEnabled = _norSceneView.visible = true;
			
			PkListUI.getInstance().checkShowUI();
			
//			_norSceneView.alpha = 0;
//			TweenLite.to(_norSceneView, .3, {alpha:1});
			
			//发送给剧情动画使用
			_model.dispatchEvent( new CustomEvent( CustomEvent.SWITCH_SCENE, null ) );
		}
		public function set isDeadWay(val:Boolean):void
		{
			_isDeadWay	=	val;
			if(WorldBossExitUI.getInstance().worldBossState == 1 || FactionBossExitUI.getInstance().worldBossState	==	1) return;
			if(_isDeadWay)
			{
				walkPoint = _walkPlacePoints[ "wait" ];
				WalkManager.getInstance().findWayLogic.updaWalkPlace( walkPoint.split( "," ) );
			}
			else
			{
				walkPoint = _walkPlacePoints.hasOwnProperty( GameData.SceneModel ) 
					? _walkPlacePoints[ GameData.SceneModel ] : _walkPlacePoints[ "normal" ];
				WalkManager.getInstance().findWayLogic.updaWalkPlace( walkPoint.split( "," ) );
			}
		}
		public function  FactionBattleWay():void
		{
			var areaName:String="";
			//战斗状态
			if(FactionAttackLogic.getInstance().BattleState)
			{
				areaName = "normal";
			}
			else
			{
				areaName =_model.scene.Role.getPlayerGuild() == FactionAttackLogic.getInstance().LeftFaction ? "leftwait" : "rightwait";
			}
			
			walkPoint = areaName == "normal" 
				? _walkPlacePoints[ GameData.SceneModel ] : _walkPlacePoints[ areaName ];
			
			WalkManager.getInstance().findWayLogic.updaWalkPlace( walkPoint.split( "," ) );
		}
		public function get norSceneView():SceneView
		{
			return _norSceneView;
		}

		public function get walkPlacePoints():Object
		{
			return _walkPlacePoints;
		}
	}
}